#!/usr/bin/env python3
#-*- coding: utf-8 -*-
import hashlib

from io import StringIO

class command(object):
    '''
    class command(object)
    '''
    def __init__(self):
        self.encoding=None
        self.head=bytearray([0x0E,0x0F])
        self.cmd=None
        self.length=None
        self.content=None
        self.packetLength=0
        self.data=bytearray(self.head)
        self.md5=None
        self.data.extend(bytearray([0x0D,0x0A]))

    def packet(self,cmd,content,_encoding="utf-8"):
        try:
            self.encoding=_encoding
            self.cmd=cmd
            self.data.extend(bytearray(self.cmd,self.encoding))
            self.data.extend(bytearray([0x0D,0x0A]))
            self.data.extend(bytearray(self.encoding.lower(),self.encoding))
            self.data.extend(bytearray([0x0D,0x0A]))
            self.length=len(content)
            self.data.extend(self.length.to_bytes(self.length.bit_length()+1,byteorder="big",signed=False))
            self.data.extend(bytearray([0x0D,0x0A]))
            self.content=content
            self.data.extend(bytearray(self.content,self.encoding))
            self.data.extend(bytearray([0x0D,0x0A]))
            self.md5=hashlib.md5(bytes(self.data)).hexdigest()
            self.data.extend(bytearray(str(self.md5),self.encoding))
            self.data.extend(bytearray([0x0D,0x0A,0x00]))
            self.packetLength=len(self.data)
            return self.data
        except Exception as e:
            return None

    def __checkMd5(self):
        self.data=None
        self.data=bytearray(self.head)
        self.data.extend(bytearray([0x0D,0x0A]))
        self.data.extend(bytearray(self.cmd,self.encoding))
        self.data.extend(bytearray([0x0D,0x0A]))
        self.data.extend(bytearray(self.encoding.lower(),self.encoding))
        self.data.extend(bytearray([0x0D,0x0A]))
        self.length=len(self.content)
        self.data.extend(self.length.to_bytes(self.length.bit_length()+1,byteorder="big",signed=False))
        self.data.extend(bytearray([0x0D,0x0A]))
        self.data.extend(bytearray(self.content,self.encoding))
        self.data.extend(bytearray([0x0D,0x0A]))
        if bytearray(str(hashlib.md5(bytes(self.data)).hexdigest()),self.encoding).decode(self.encoding) == self.md5:
            return True
        return False

    def unpacket(self,args,_encoding="utf-8"):
        self.encoding=_encoding
        offset=0
        _r=0x0D
        _n=0x0A
        if args[0]==0x0E and args[1]==0x0F: #判断数据包头
            offset=offset+4                 #偏移指向指令字节
            temp = bytearray()              #临时变量
            for o in range(offset,len(args)):
                if args[o]==_r:
                    if o+1 <= len(args):
                        if args[o+1]==_n:
                            self.cmd=temp.decode(self.encoding)
                            temp.clear()
                            offset=o+2
                            break
                else:
                    temp.extend([args[o]])
            if self.cmd:
                for o in range(offset,len(args)):
                    if args[o]==_r:
                        if o+1<=len(args):
                            if args[o+1]==_n:
                                self.encoding=bytearray.decode(temp)
                                temp.clear()
                                offset=o+2
                                break
                    else:
                        temp.extend([args[o]])
                for o in range(offset,len(args)):
                    if args[o]==_r:
                        if o+1 <= len(args):
                            if args[o+1]==_n:
                                self.length=int.from_bytes(temp,byteorder="big",signed=False)
                                temp.clear()
                                offset=o+2
                                break
                    else:
                        temp.extend([args[o]])
                if self.length:
                    if offset+self.length<=len(args):
                        temp[0:self.length]=args[offset:offset+self.length]
                        self.content = temp.decode(self.encoding)
                        temp.clear()
                        offset=offset+self.length+2
                        for o in range(offset,len(args)):
                            if args[o]==_r:
                                if o+1 <= len(args):
                                    if args[o+1]==_n:
                                        if o+2<=len(args):
                                            if args[o+2]==0x00:
                                                self.md5=temp.decode(self.encoding)
                                                temp.clear()
                            else:
                                temp.extend([args[o]])
                        if self.__checkMd5():#数据块验证
                            return self
        return None
            
